﻿using System;
using System.Linq;
using COMMON;
using VO;
using System.Collections.Generic;

namespace DAL
{
    public class ClienteDAL
    {

        #region SelectClienteSorteio
        /// <summary>
        /// Sorteia um Clientes que năo existam na tabela de fila,Historico de atendimento com status de sucesso e blacklist
        /// </summary>
        /// <returns></returns>
        public Cliente SelectClienteSorteio(Cliente obCliente)
        {
            Cliente cliente = null;

            using (var data = new CallcenterEntities())
            {
                var consulta = (from tb in data.CCCliente_Callcenter
                                join tbcc in data.tbCCCampanha_Cliente on tb.idCliente equals tbcc.idCliente
                                join tbca in data.tbCCCampanha_Atendente on tbcc.idCampanha equals tbca.idCampanha
                                where (tbca.idCampanha == obCliente.idCampanha || obCliente.idCampanha == 0)
                                      && tbca.idAtendente == obCliente.idAtendente
                                       && !(from tbF in data.tbCCFila select tbF.idCliente).Contains(tb.idCliente)
                                       && !(from tbHa in data.tbCCHistoricoAtendimento
                                            where tbHa.idStatus == (int)Enumerator.StatusAtendimento.Sucesso 
                                            select tbHa.idCliente).Distinct().Contains(tb.idCliente)
                                       && !(from tbBl in data.tbCCBlackList select tbBl.cpf).Contains(tb.CPF)
                                       && !(from tbAgen in data.tbCCClienteAgendamento where tbAgen.dataAgendamento <= DateTime.Now select tbAgen.idCliente).Contains(tb.idCliente)
                                       && (tb.fgAtivo == null || tb.fgAtivo)
                                select new { tb.idCliente, tb.Nome, tbca.idCampanha }).ToList();

                if (consulta != null && consulta.Count > 0)
                {
                    int count = consulta.Count(); // 1st round-trip
                    int index = new Random().Next(count);

                    var consultaFinal = consulta.Skip(index).FirstOrDefault(); // 2nd round-trip

                    if (consultaFinal != null)
                        cliente = new Cliente
                                      {
                                          idCliente = consultaFinal.idCliente,
                                          nmCliente = consultaFinal.Nome,
                                          idCampanha = consultaFinal.idCampanha
                                      };
                }
            }
            return cliente;
        }
        #endregion

        #region SelectInicialCliente
        /// <summary>
        /// Retorna inicial dos clientes
        /// </summary>
        /// <returns></returns>
        public IList<Cliente> SelectInicialCliente()
        {
            using (var data = new CallcenterEntities())
            {
                var consulta = (from tb in data.CCCliente_Callcenter
                                //where (tb.nmCliente != null && tb.nmCliente.Trim() != "")
                                group tb by tb.Nome.Substring(0, 1).ToUpper() into g
                                select new Cliente { nmCliente = g.Key }).Where(c => c.nmCliente.Replace("\t", "").Trim().Length > 0).OrderBy(c => c.nmCliente).ToList();
                //select tb);

                return consulta;
            }
        }
        #endregion


        #region SelectCliente
        /// <summary>
        /// Retorna um cliente
        /// </summary>
        /// <returns></returns>
        public IList<Cliente> SelectCliente()
        {
            using (var data = new CallcenterEntities())
            {
                var consulta = (from tb in data.CCCliente_Callcenter
                                where (tb.Nome != null && tb.Nome.Trim() != "") && (tb.fgAtivo || tb.fgAtivo == null) && !(from tb2 in data.tbCCBlackList select tb2.idCliente).Contains(tb.idCliente)
                                orderby tb.Nome
                                select tb);

                var cliente = PopulaObjeto(consulta);

                return cliente.OrderBy(c => c.nmCliente).ToList();
            }
        }


        public IList<Cliente> SelectClientePesquisa(FiltroCliente obj)
        {
            using (var data = new CallcenterEntities())
            {
                IQueryable<CCCliente_Callcenter> consulta = null;

                if (obj.fgBlackList == 1)
                {
                    consulta = (from tb in data.CCCliente_Callcenter
                                join tbC in data.tbCCCampanha_Cliente on tb.idCliente equals tbC.idCliente
                                where (tb.Nome.Contains(obj.Nome) || obj.Nome == "") && (from tb2 in data.tbCCBlackList select tb2.idCliente).Contains(tb.idCliente)
                                && (obj.CPF == "" || tb.CPF == obj.CPF)
                                orderby tb.Nome
                                select tb).Distinct();
                }
                else
                {
                    consulta = (from tb in data.CCCliente_Callcenter
                                join tbC in data.tbCCCampanha_Cliente on tb.idCliente equals tbC.idCliente
                                where (tb.Nome.Contains(obj.Nome) || obj.Nome == "") && !(from tb2 in data.tbCCBlackList select tb2.idCliente).Contains(tb.idCliente)
                                && (obj.CPF == "" || tb.CPF == obj.CPF)
                                orderby tb.Nome
                                select tb).Distinct();
                }




                var cliente = PopulaObjeto(consulta);

                return cliente.OrderBy(c => c.nmCliente).ToList();
            }
        }


        /// <summary>
        /// Retorna um cliente pelo idCliente
        /// </summary>
        /// <returns></returns>
        public Cliente SelectCliente(int idCliente)
        {
            using (var data = new CallcenterEntities())
            {
                var consulta = (from tb in data.CCCliente_Callcenter
                                join tb2 in data.tbCCCampanha_Cliente on tb.idCliente equals tb2.idCliente
                                join tb3 in data.tbCCCampanha on tb2.idCampanha equals tb3.idCampanha
                                where tb.idCliente == idCliente
                                select new Cliente
                                {
                                    idCliente = tb.idCliente,
                                    nmCliente = tb.Nome,
                                    CPF = tb.CPF,
                                    NomeCampanha = tb3.nomeCampanha,
                                    idade = tb.Idade,
                                    UF = tb.UF,
                                    cidade = tb.Cidade,
                                    bairro = tb.Bairro,
                                    CEP = tb.Cep,
                                    PMT = tb.PMT,
                                    score = tb.Score,
                                    banco = tb.Bancos,
                                    convenio = tb.Convenio,
                                    margem = tb.Margem_Fixa,
                                    prazo = tb.Prazo,
                                    descricao = tb3.descricao
                                }).FirstOrDefault();

                return consulta;
            }
        }
        #endregion

        #region SelectClienteFiltro
        /// <summary>
        /// Retorna lista de cliente
        /// </summary>
        /// <returns></returns>
        public List<Cliente> SelectClienteFiltro(Cliente obj)
        {
            using (var data = new CallcenterEntities())
            {
                var consulta = (from tb in data.tbCCCampanha_Cliente
                                join tb2 in data.CCCliente_Callcenter on tb.idCliente equals tb2.idCliente
                                join tb3 in data.tbCCCampanha on tb.idCampanha equals tb3.idCampanha
                                join tb4 in data.tbCCFila on tb2.idCliente equals tb4.idCliente into x
                                from tb4 in x.DefaultIfEmpty()
                                where
                                    (tb2.CPF.Contains(obj.CPF) || obj.CPF == string.Empty) &&
                                    (tb2.Nome.Contains(obj.nmCliente) || obj.nmCliente == string.Empty)
                                    && (from atend in data.tbCCCampanha_Atendente
                                        where atend.idAtendente == obj.idAtendente
                                        && (atend.idCampanha == obj.idCampanha || obj.idCampanha == 0)
                                        select atend.idCampanha).Contains(tb.idCampanha)
                                    //&& !(from tbF in data.tbCCFila select tbF.idCliente).Contains(tb.idCliente)
                                    && !(from tbHa in data.tbCCHistoricoAtendimento where tbHa.idStatus ==(int)Enumerator.StatusAtendimento.Sucesso select tbHa.idCliente).Contains(tb.idCliente)
                                    && !(from tbBl in data.tbCCBlackList where tbBl.cpf == tb2.CPF select tbBl.idCliente).Contains(tb.idCliente)
                                select new Cliente
                                {
                                    idCampanha = tb.idCampanha,
                                    nmCliente = tb2.Nome,
                                    CPF = tb2.CPF,
                                    NomeCampanha = tb3.nomeCampanha,
                                    idCliente = tb.idCliente,
                                    idAtendente = tb4.idAtendente != null ? tb4.idAtendente : 0
                                }).ToList();

                return consulta;
            }
        }

        public List<Cliente> SelectClienteFiltro(FiltroCliente obj)
        {
            using (var data = new CallcenterEntities())
            {
                
                var consulta = (from tb in data.CCCliente_Callcenter
                                where tb.CPF.Contains(obj.CPF)
                                && tb.Nome.Contains(obj.Nome)
                                && (obj.UF.Contains(tb.UF) || obj.UF.Count.Equals(0))
                                && (obj.Cidade.Contains(tb.Cidade) || obj.Cidade.Count.Equals(0))
                                && (obj.Bairro.Contains(tb.Bairro) || obj.Bairro.Count.Equals(0))
                                && tb.Cep.Contains(obj.CEP)
                                &&(obj.PMTDe==null || tb.PMT>=obj.PMTDe) && (obj.PMTAte==null || tb.PMT<=obj.PMTAte)
                                && (obj.ScoreDe == null || tb.Score >= obj.ScoreDe) && (obj.ScoreAte == null || tb.Score <= obj.ScoreAte)
                                && (obj.MargemDe == null || tb.Margem_Fixa >= obj.MargemDe) && (obj.MargemAte == null || tb.Margem_Fixa <= obj.MargemAte)
                                && (obj.PrazoDe == null || tb.Prazo >= obj.PrazoDe) && (obj.PrazoAte == null || tb.Prazo <= obj.PrazoAte)
                                && (obj.Bancos.Contains(tb.Bancos) || obj.Bancos.Count.Equals(0))
                                && (obj.Convenio.Contains(tb.Convenio) || obj.Convenio.Count.Equals(0))
                                && (obj.IdadeDe == 0 || tb.Idade >= obj.IdadeDe) && (obj.IdadeAte == 0 || tb.Idade <= obj.IdadeAte)
                                && !(from tb2 in data.tbCCCampanha_Cliente where tb2.idCampanha == obj.idCampanha select tb2.idCliente).Contains(tb.idCliente)
                                //&& (obj.fgPensionista == 100 || tb.flgPensionista == objP)
                                && (obj.strOrgao == null || tb.Orgao == obj.strOrgao)
                                orderby tb.Nome
                                select new Cliente { idade = tb.Idade, UF = tb.UF, idCliente = tb.idCliente, nmCliente = tb.Nome }).ToList();
                //&& ((obj.PMT != null && (obj.TipoPMT.Equals(0) ? tb.PMT > obj.PMT : obj.TipoPMT.Equals(1) ? tb.PMT == obj.PMT : tb.PMT < obj.PMT)) || obj.PMT == null)
                //&& ((obj.Score != null && (obj.TipoScore.Equals(0) ? tb.Score > obj.Score : obj.TipoScore.Equals(1) ? tb.Score == obj.Score : tb.Score < obj.Score)) || obj.Score == null)
                //&& ((obj.Margem != null && (obj.TipoMargem.Equals(0) ? tb.Margem_Fixa > obj.Margem : obj.TipoMargem.Equals(1) ? tb.Margem_Fixa == obj.Margem : tb.Margem_Fixa < obj.Margem)) || obj.Margem == null)
                //&& ((obj.Prazo != null && (obj.TipoPrazo.Equals(0) ? tb.Prazo > obj.Prazo : obj.TipoPrazo.Equals(1) ? tb.Prazo == obj.Prazo : tb.Prazo < obj.Prazo)) || obj.Prazo == null)
                //&& ((!obj.Idade.Equals(0) && (obj.TipoIdade.Equals(0) ? tb.Idade > obj.Idade : obj.TipoIdade.Equals(1) ? tb.Idade == obj.Idade : tb.Idade < obj.Idade)) || obj.Idade.Equals(0))
                return consulta;
            }
        }
        #endregion

        #region SelectUFFiltro
        public IList<string> SelectUFFiltro()
        {
            var contexto = new CallcenterEntities();

            var list = (from tb in contexto.CCCliente_Callcenter
                        orderby tb.UF
                        select tb.UF).Distinct().ToList();

            return list;
        }
        #endregion

        #region SelectCidadeFiltro
        public IList<string> SelectCidadeFiltro()
        {
            var contexto = new CallcenterEntities();

            var list = (from tb in contexto.CCCliente_Callcenter
                        orderby tb.Cidade
                        select tb.Cidade).Distinct().ToList();

            return list;
        }
        #endregion

        #region SelectBairroFiltro
        public IList<string> SelectBairroFiltro()
        {
            var contexto = new CallcenterEntities();

            var list = (from tb in contexto.CCCliente_Callcenter
                        //orderby tb.Bairro
                        select tb.Bairro).Distinct().OrderBy(c => c).ToList();

            return list;
        }
        #endregion

        #region SelectBancosFiltro
        public IList<string> SelectBancosFiltro()
        {
            var contexto = new CallcenterEntities();

            var list = (from tb in contexto.CCCliente_Callcenter
                        orderby tb.Bancos
                        select tb.Bancos).Distinct().ToList();

            return list;
        }
        #endregion

        #region SelectConvenioFiltro
        public IList<string> SelectConvenioFiltro()
        {
            var contexto = new CallcenterEntities();

            var list = (from tb in contexto.CCCliente_Callcenter
                        orderby tb.Convenio
                        select tb.Convenio).Distinct().ToList();

            return list;
        }
        #endregion

        #region AlteraDataReAgendamento
        public void AlteraDataReAgendamento(Cliente cliente)
        {
            using (var data = new CallcenterEntities())
            {
                var objCliente = (from tb in data.CCCliente_Callcenter
                                  where tb.idCliente == cliente.idCliente
                                  select tb).FirstOrDefault();
                objCliente.dtReAgendamento = cliente.dtReagendamento;
                data.SaveChanges();
            }

        }
        #endregion

        #region AlteraBloqueio
        public void AlteraBloqueio(Cliente cliente)
        {
            using (var data = new CallcenterEntities())
            {
                var objCliente = (from tb in data.CCCliente_Callcenter
                                  where tb.idCliente == cliente.idCliente
                                  select tb).FirstOrDefault();
                objCliente.fgAtivo = cliente.fgAtivo;
                data.SaveChanges();
            }

        }
        #endregion


        public void RetornaClienteParaSorteio(List<FiltroCliente> obj)
        {
            var data = new CallcenterEntities();
            //Remove cliente do blackList
            foreach (var query in obj.Select(item => (from tb in data.tbCCBlackList where tb.idCliente == item.idCliente select tb).FirstOrDefault()).Where(query => query != null))
            {
                data.tbCCBlackList.DeleteObject(query);
            }

            //Remove cliente da Fila
            foreach (var query in obj.Select(item => (from tb in data.tbCCFila where tb.idCliente == item.idCliente select tb).FirstOrDefault()).Where(query => query != null))
            {
                data.tbCCFila.DeleteObject(query);
            }

            //Remove cliente dos agendamentos
            foreach (var query in obj.Select(item => (from tb in data.tbCCClienteAgendamento where tb.idCliente == item.idCliente select tb).FirstOrDefault()).Where(query => query != null))
            {
                data.tbCCClienteAgendamento.DeleteObject(query);
            }

            data.SaveChanges();

        }

        #region PopulaObjeto
        protected static CCCliente_Callcenter PopulaObjeto(Cliente obj, CCCliente_Callcenter tabela)
        {
            tabela.Nome = obj.nmCliente;
            tabela.dtReAgendamento = obj.dtReagendamento;
            tabela.fgAtivo = obj.fgAtivo;
            return tabela;
        }

        protected static IList<Cliente> PopulaObjeto(IQueryable<CCCliente_Callcenter> reader)
        {
            return reader.Select(obj => new Cliente
                                            {
                                                idCliente = obj.idCliente,
                                                nmCliente = obj.Nome,
                                                CPF = obj.CPF
                                            }).ToList();
        }
        #endregion

    }
}